package model

import (
	"context"
	"encoding/json"
	"fmt"
	"strings"

	"github.com/zeromicro/go-zero/core/stores/sqlx"
)

var _ SysRoleModel = (*customSysRoleModel)(nil)

type (
	// SysRoleModel is an interface to be customized, add more methods here,
	// and implement the added methods in customSysRoleModel.
	SysRoleModel interface {
		sysRoleModel
		withSession(session sqlx.Session) SysRoleModel
		FindRolePage(ctx context.Context, offset int, size int) ([]SysRole, error)
		FindRoleCount(ctx context.Context) (int, error)
		FindRoleByIds(ctx context.Context, ids string) ([]SysRole, error)
	}

	customSysRoleModel struct {
		*defaultSysRoleModel
	}
)

func (m *customSysRoleModel) FindRoleByIds(ctx context.Context, ids string) ([]SysRole, error) {
	var roleIds []int
	err := json.Unmarshal([]byte(ids), &roleIds)
	if err != nil {
		return nil, err
	}
	// 构造正确的占位符
	placeholders := strings.Repeat("?,", len(roleIds)-1) + "?"
	query := fmt.Sprintf("SELECT %s FROM %s WHERE roleId IN (%s)",
		sysRoleRows,
		m.table,
		placeholders)

	// 转换参数类型
	args := make([]interface{}, len(roleIds))
	for i, id := range roleIds {
		args[i] = id
	}

	var roles []SysRole
	err = m.conn.QueryRowsCtx(ctx, &roles, query, args...)
	if err != nil {
		return nil, err
	}
	return roles, nil
}

func (m *customSysRoleModel) FindRoleCount(ctx context.Context) (int, error) {
	query := fmt.Sprintf("select count(*) from %s", m.table)
	var count int
	err := m.conn.QueryRowCtx(ctx, &count, query)
	if err != nil {
		return 0, err
	}
	return count, err
}

func (m *customSysRoleModel) FindRolePage(ctx context.Context, offset int, size int) ([]SysRole, error) {
	query := fmt.Sprintf("select %s from %s order by roleId desc limit  ?,? ", sysRoleRows, m.table)
	var roles []SysRole
	err := m.conn.QueryRowsCtx(ctx, &roles, query, offset, size)
	if err != nil {
		return nil, err
	}
	return roles, nil
}

// NewSysRoleModel returns a model for the database table.
func NewSysRoleModel(conn sqlx.SqlConn) SysRoleModel {
	return &customSysRoleModel{
		defaultSysRoleModel: newSysRoleModel(conn),
	}
}

func (m *customSysRoleModel) withSession(session sqlx.Session) SysRoleModel {
	return NewSysRoleModel(sqlx.NewSqlConnFromSession(session))
}
